<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<title>event事件流</title>
<!--autor: carriehuang | QQ:453555909 | 转载需注明原处-->
<head>
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        .div{
        	padding: 40px;
        }
        .div1{
        	background-color: red;
        }
        .div2{
        	background-color: blue;
        }
        .div3{
        	background-color: yellow;
        }
    </style>
</head>
<body>
<div class="div div1" id="j_div1">
	<div class="div div2" id="j_div2">
		<div class="div div3" id="j_div3"></div>
	</div>
</div>


<script type="text/javascript">
/*
 * 事件流： 跟样式无关，是根据结构嵌套有关
 * 1、事件冒泡：当一个元素接收到事件的时候，会把它接收到的所有事件传播给它的父级，一直到顶层，从里到外，就是事件中的冒泡机制。默认会存在的
 * 单独阻止冒泡:请使用 event.stopPropagation() 方法来代替event.cancelBubble不标准的属性.
 * 2、事件捕获：ie下没有的，在绑定事件中，标准下是有的
 * 
 * 事件函数绑定: 把一个函数赋值给一个事件 ，把一个东西和另一个东西关联就是绑定,它一共有两种形式。
 * */
    window.onload=function(){
       
        var oDiv1 = document.getElementById("j_div1");
        var oDiv2 = document.getElementById("j_div2");
        var oDiv3 = document.getElementById("j_div3");
		 	 
		 	function fn1(){
		 		alert(this.id);
		 	}
		 	function fn2(ev){
		 		var ev = ev || event;
		 		//ev.cancelBubble = true;
		 		ev.stopPropagation();
		 		alert(this.id);
		 	}
		 	function fn3(){
		 		alert(1+this);
		 	}
		 	function fn4(){
		 		alert(2);
		 	}
		 	//事件绑定的第一种形式：是给一个对象绑定的一个事件处理函数的第一种形式
		 	oDiv1.onclick = fn1;//告诉DIV1如果它接收到了一个点击事件，它就去执行fn1
		  	oDiv2.onclick = fn1;
		  	oDiv3.onclick = fn2;  //并不影响oDiv1给oDiv2、oDiv3添加了点击事件
		  	
		  	
		  	
		  	
		  	//事件绑定的第二种形式：给一个对象的同一个事件绑定多个不同的函数
		  	/*兼容：
		  	 *ie： obj.attachEvent(事件名称,事件函数) 
		  	 *标准（ie9以上，以及其他高版本浏览器）：obj.addEventListener(事件名称,事件函数,是否捕获) ， 是否捕获:默认是false(冒泡出去)，true(捕获进来)
		  	 * 
		  	 *区别：
		  	 * 1、有无捕获（ie下没有捕获）
		  	 * 2、事件名称有无on
		  	 * 3、事件执行顺序是倒序还是正序（attachEvent 标准ie（ie9以上）——>正序，非标准ie——>倒序；addEventListener正序）
		  	 * 4、this触发该事件的对象 （attachEvent ——>window；addEventListener——>document）
		  	 * */
		  	//document.attachEvent('onclick', fn3);
		    //document.attachEvent('onclick', fn3);
		  	
		  	//document.addEventListener('click',fn3,false);
		  	//document.addEventListener('click',fn4,false);
		  	
		  	/* call:函数下的一个方法，call方法第一个参数可以改变函数执行过程中的内部this的指向，例如： 
			 * function fn(){
			 		alert(this);
			 	}
			 	fn.call(1); //fn() == fn.call()
			 	结果是1
			 *	call方法第二个参数开始就是原来函数的参数列表，例如
			 *	function fn(a,b){
			 		alert(this);
			 		alert(a+b);
			 	}
			 	fn.call(1,10,20); //如果第一个参数是null，则为原本的对象window
		  	*/
		  	
		  	//封装函数，使事件绑定的第二种形式能够在不同浏览器下都兼容
		  	function bind(obj,evname,fn){
		  		if(obj.addEventListener){
		  			obj.addEventListener(evname,fn,false);
		  		}else{
		  			obj.attachEvent('on'+evname,function(){
		  				fn.call(obj);
		  			})
		  		}
		  	}
		  	//可以绑定多个事件
		  	bind(document,'click',fn3); 
		  	bind(document,'click',fn4);
		}
</script>
</body>

</html>
